<!--
 * @LastEditTime: 2023-11-16 17:29:32
 * @FilePath: \bdcar-net\src\views\statisticalReportForm\multimediaData.vue
 * @Description: 多媒体数据
-->
<template>
  <div class="app-container" v-loading="loading">
    <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="设备名称" prop="numberPlate">
        <el-input v-model="queryParams.numberPlate" placeholder="请输入设备名称" clearable @keyup.enter="handleQuery" />
      </el-form-item>
      <el-form-item label="所属公司" prop="companyId">
        <el-tree-select v-model="queryParams.companyId" placeholder="请选择所属公司" clearable :data="treeList"
          :expand-on-click-node="false" :render-after-expand="false" @change="handleQuery" check-strictly
          :props="{ label: 'label' }" node-key="id" filterable />
      </el-form-item>
      <el-form-item label="拍摄时间" style="width: 428px;">
        <el-date-picker v-model="dateRange" value-format="YYYY-MM-DD HH:mm:ss" type="datetimerange" :default-time="[new Date(2000, 1, 1, 0, 0, 0),
        new Date(2000, 2, 1, 23, 59, 59),]" range-separator="-" start-placeholder="开始时间"
          end-placeholder="结束时间"></el-date-picker>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
        <el-button icon="Refresh" @click="resetQuery">重置</el-button>
        <el-popover placement="bottom" :width="220" trigger="click" :visible="visible" :persistent='false'>
          <template #reference>
            <el-button icon="Setting" @click="visible = true"
              v-hasPermi="['statisticalReportForm:multimediaData:set']">设置</el-button>
          </template>
          <el-form-item label="行数目" prop="row">
            <el-input-number v-model="arrParam.row" placeholder="请输入行数目" />
          </el-form-item>
          <el-form-item label="列数目" prop="col">
            <el-input-number v-model="arrParam.col" placeholder="请输入列数目" />
          </el-form-item>
          <div style="text-align: right;">
            <el-button @click="visible = false">取消</el-button>
            <el-button type="primary" @click="setNewRange">保存</el-button>
          </div>
        </el-popover>
      </el-form-item>
    </el-form>
    <div class="photoContainer">
      <div style="overflow: auto;width: 100%;height: 100%;">
        <ul class="photoRow" v-for="(v, i) in arrange" :key="i">
          <li class="photoItem" v-for="(item, index) in v" :key="index" @click="handleOpenDetail(item, i, index)">
            <div style="width:100%;height:120px;position: relative;">
              <div style="position: absolute;bottom: 0;width:100%;height: 21px;display: flex;">
                <div class="item-channel">通道{{ item.channelId }}</div>
                <div class="time-text">{{ item.time }}</div>
              </div>
              <el-image style="width: 100%;height: 100%;" :src="getImgSrc(item.pictureUrl)" v-if="item.pictureUrl">
              </el-image>
              <div v-else-if="!item.pictureUrl"
                style="text-align: center;line-height: 120px;color: #2d384e;background:#F5F7FA;">
                暂无图片
              </div>
            </div>
            <div class="item-info">
              <div class="item-title">{{ item.numberPlate }}</div>
              <div class="item-text overflow-text" :title="item.companyName">{{ item.companyName }}</div>
              <div class="item-text overflow-text" :title="item.location">
                <el-icon>
                  <Location />
                </el-icon>{{ item.location }}
              </div>
            </div>
          </li>
        </ul>
        <div v-if="arrange.length == 0"
          style="display: flex;align-items: center;flex-direction: column;height: 100%; justify-content: center;">
          <img src="@/assets/img/index/nodata.png" />
        </div>
      </div>
    </div>
    <pagination v-show="total > 0" layout="total, prev, pager, next, jumper" :total="total"
      v-model:page="queryParams.pageNum" @pagination="getList" :limit='queryParams.pageSize'
      style="background-color: unset;" />

    <!-- 详情 -->
    <el-dialog title="图片详情" v-model="detailOpen" width="1100px" append-to-body destroy-on-close>
      <div class="body" style="height: 558px;overflow: auto;">
        <div class="body-top">
          <div class="img-dom">
            <el-image id="imgFull" style="width: 100%;height: 100%;" :src="getImgSrc(currentDetailInfo.pictureUrl)">
            </el-image>
            <div class="img-top">
              <div class="chanel-text">通道{{ currentDetailInfo.channelId }}</div>
              <div class="other-text">
                <span>{{ currentDetailInfo.numberPlate }}</span>
                <span class="company-name">{{ currentDetailInfo.companyName }}</span>
              </div>
            </div>
            <div class="img-left" @click="handleNextClick('left')">
              <img src="@/assets/img/arrow.png" alt="">
            </div>
            <div class="img-right" @click="handleNextClick('right')">
              <img src="@/assets/img/arrow.png" alt="">
            </div>
            <div class="img-bottom">
              <!-- <div class="downAndFull" @click="downloadImage(currentDetailInfo.pictureUrl)">
                <img src="@/assets/img/download.png" alt="">
                下载
              </div> -->
              <div class="downAndFull" @click="fullScreen">
                <img src="@/assets/img/fullscreen.png" alt="">
                全屏
              </div>
            </div>
          </div>
          <div class="map-dom">
            <div id="trajectory_container"></div>
            <div class="info-dom">
              <div class="info-top">
                <div class="driver-dom">
                  <div class="carNum">{{ currentDetailInfo.numberPlate }}</div>
                  <div class="name">
                    <img src="@/assets/img/driver.png" alt="" style="margin-right: 4px;">
                    {{ currentDetailInfo.driverName }}
                  </div>
                </div>
                <div class="speed-dom">
                  <div class="s-top">速度</div>
                  <div class="s-bottom">{{ currentDetailInfo.spd }}km/h</div>
                </div>
              </div>
              <div class="bottom-dom">定位时间<span class="content">{{ currentDetailInfo.time }}</span></div>
              <div class="bottom-dom">定位位置<span class="content">{{ currentDetailInfo.location }}</span></div>
            </div>
          </div>
        </div>
        <div class="body-bottom">
          <div class="arrow-left" @click="leftArrowClick" disabled>
            <img src="@/assets/img/arrow.png" alt="">
          </div>
          <ul class="img-list">
            <li class="img-item" v-for="(v, i) in dataListObj[currentGroupIndex]" :key="i" @click="detailItemClick(v)">
              <img :src="getImgSrc(v.pictureUrl)" alt="">
              <!-- 设备号+通道号+时间 是唯一键值 -->
              <div class="item-mask"
                :class="{ 'item-active': (currentDetailInfo.dvo == v.dvo && currentDetailInfo.channelId == v.channelId && currentDetailInfo.time == v.time) }">
              </div>
            </li>
          </ul>
          <div class="arrow-right" @click="rightArrowClick">
            <img src="@/assets/img/arrow.png" alt="">
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>
<script setup lang="ts" name="MultimediaData">
import dayjs from "dayjs";
import { initMap, addLotsOfPoints } from '../../utils/map/leafletMap';
import { reactive, toRefs, ref, getCurrentInstance, onDeactivated, nextTick } from "vue";
import { treeDept } from "../../api/system/dept";
import { getTrackByid } from "../../api/trajectoryMonitor/trajectoryTrack";
import request from '../../utils/request';
const loading = ref(true);
const visible = ref(false);
const arrange = ref([]);
const arrParam = ref({
  row: 3, //行
  col: 8,  //列
});
const dateRange = ref([dayjs(new Date()).format("YYYY-MM-DD 00:00:00"), dayjs(new Date()).format("YYYY-MM-DD 23:59:59")]);
const { proxy } = getCurrentInstance();
const total = ref(0);
const showSearch = ref(true);
const data = reactive({
  queryParams: {
    pageNum: 1,
    pageSize: 10,
    numberPlate: null,
    companyId: null,
  },
});
const treeList = ref([]);
treeDept().then(res => {
  treeList.value = res.data
});
const { queryParams } = toRefs(data);
onDeactivated(() => {
  visible.value = false;
})
// 详情
const detailOpen = ref(false)
const currentDetailInfo: any = ref({})
let map = null
let dataList = []
const dataListObj: any = ref({}); //详情切换数据对象组（5个一组）
const currentGroupIndex = ref(0)  //当前选中项组数
let groupNum = 0  //组数
let activeGroupIndex = 0  //当前组选中项索引
let pathList = []//储存当前地图展示的轨迹点
let trackLayer = null// 轨迹图层
let trackPointsLayer = null//轨迹点集合图层


/** 搜索按钮操作 */
function handleQuery() {
  queryParams.value.pageNum = 1;
  getList();
}

/** 重置按钮操作 */
function resetQuery() {
  //@ts-ignore
  proxy.resetForm("queryRef");
  dateRange.value = [dayjs(new Date()).format("YYYY-MM-DD 00:00:00"), dayjs(new Date()).format("YYYY-MM-DD 23:59:59")];
  handleQuery();
}

/** 查询列表 */
function getList() {
  loading.value = true;
  queryParams.value.pageSize = arrParam.value.row * arrParam.value.col;
  let _param = { ...queryParams.value, startTime: dateRange.value?.[0], endTime: dateRange.value?.[1] };
  request({
    url: '/comlbs/reportStatistics/photo/list',
    method: 'post',
    params: _param
  }).then(({ data }: any) => {
    arrange.value = [];
    data.list.forEach((v, i) => {
      let _x = parseInt((i / arrParam.value.col + ''));
      if (!arrange.value[_x]) arrange.value[_x] = [];
      arrange.value[_x].push(v);
    });
    dataList = data.list
    total.value = data.total;
    loading.value = false;

    groupNum = parseInt(((dataList.length / 5) + ''));
    for (let i = 0; i <= groupNum; i++) {
      dataListObj.value[i] = dataList.slice(i * 5, (i + 1) * 5)
    }
  }).catch(err=>{
    loading.value = false;
  });
}

/** 设置照片墙行列 */
function getRange() {
  request({
    url: '/comlbs/photoWallConfig/getConfig',
    method: 'post',
  }).then(({ data }: any) => {
    arrParam.value = {
      row: data.row, //行
      col: data.col,  //列
    };
    getList();
  });
}

/** 设置照片墙行列 */
function setNewRange() {
  request({
    url: '/comlbs/photoWallConfig/saveConfig',
    method: 'post',
    data: {
      "col": arrParam.value.col,
      "row": arrParam.value.row,
    }
  }).then(({ data }: any) => {
    visible.value = false;
    getList();
  });
}
function getImgSrc(val: string) {
  if (val) {
    //@ts-ignore
    return import.meta.env.VITE_APP_BASE_API + val;
  }
  else return "";
}

// i,index 表示点击的是第i行第index个（i,index均从0开始）照片的详情
function handleOpenDetail(item, i, index) {
  detailOpen.value = true
  currentDetailInfo.value = item
  //dom生成以后才能挂载地图
  nextTick(() => {
    initMap("trajectory_container").then(_map => {
      map = _map
      //@ts-ignore
      trackLayer = new L.featureGroup([]).addTo(map);
      showTrackLayer()
    })
  })
  // 索引
  let itemIndex = i * arrParam.value.col + index
  currentGroupIndex.value = parseInt((itemIndex / 5 + ''))
  activeGroupIndex = itemIndex % 5 // 范围[0,4]
}
// 展示轨迹
function showTrackLayer() {
  // 拍摄前后5分钟轨迹
  pathList = []
  trackPointsLayer && trackPointsLayer.clearLayers()
  trackLayer && trackLayer.clearLayers()
  let starttime = dayjs(currentDetailInfo.value.time).add(-5, "minutes").format("YYYY-MM-DD HH:mm:ss");
  let endtime = dayjs(currentDetailInfo.value.time).add(5, "minutes").format("YYYY-MM-DD HH:mm:ss");
  getTrackByid(currentDetailInfo.value.dvo, starttime, endtime).then(result => {
    if (result.code == 200) {
      result.data.forEach(v => {
        pathList.push([v.lat, v.lng])
      })
      addTrackLine()
    }
  })
}
function addTrackLine() {
  const polylinenObj = {
    fillColor: '#0066FF', // 多边形填充颜色
    weight: 4, // 线条宽度，默认为 1
    color: '#0066FF', // 线条颜色
  };
  //@ts-ignore
  // 添加轨迹线
  let layerLine = L.polyline(pathList, { ...polylinenObj }).addTo(trackLayer);
  // 添加轨迹点
  function _openPopup(e) {
    // _this.showPopup(e.layer.attribution, "trackPoint", "轨迹点")
  }
  addLotsOfPoints(map, pathList, _openPopup).then(layer => {
    trackPointsLayer = layer
  })
  //@ts-ignore
  // 添加拍摄点
  L.marker([currentDetailInfo.value.lat, currentDetailInfo.value.lng]).addTo(trackLayer)

  map.fitBounds(trackLayer.getBounds());
}
function leftArrowClick() {
  if (currentGroupIndex.value > 0) currentGroupIndex.value = currentGroupIndex.value - 1
}
function rightArrowClick() {
  if (currentGroupIndex.value < groupNum) currentGroupIndex.value = currentGroupIndex.value + 1
}
function handleNextClick(type) {
  if (type == 'left') {
    if (activeGroupIndex == 0) {
      currentGroupIndex.value = currentGroupIndex.value - 1
      activeGroupIndex = 4
      if (currentGroupIndex.value < 0) return
    } else {
      activeGroupIndex = activeGroupIndex - 1
      currentDetailInfo.value = dataListObj.value[currentGroupIndex.value][activeGroupIndex]
    }
    currentDetailInfo.value = dataListObj.value[currentGroupIndex.value][activeGroupIndex]
  } else {
    if (activeGroupIndex == 4) {
      currentGroupIndex.value = currentGroupIndex.value + 1
      activeGroupIndex = 0
      if (currentGroupIndex.value > groupNum) return
    }
    else {
      activeGroupIndex = activeGroupIndex + 1
    }
    currentDetailInfo.value = dataListObj.value[currentGroupIndex.value][activeGroupIndex]
  }
  // 轨迹
  showTrackLayer()
}
function detailItemClick(item) {
  currentDetailInfo.value = item
  // 轨迹
  showTrackLayer()
}
// 全屏
function fullScreen() {
  //@ts-ignore
  let isFull = document.fullscreenElement || document.msFullscreenElement || document.mozFullscreenElement || document.webkitFullscreenElement || false;
  let mapBoxContainer = document.getElementById("imgFull");
  if (!isFull) {
    requestFullScreen(mapBoxContainer);    //如果不存在全屏元素，说明是缩小状态，调用全屏函数
  }
}
//全屏函数
function requestFullScreen(element) {
  var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen || false;
  if (requestMethod) {
    requestMethod.call(element);
  }
}
// 下载图片
function downloadImage(val) {
  // 创建一个隐藏的链接
  const link = document.createElement('a');
  //@ts-ignore
  link.href = import.meta.env.VITE_APP_BASE_API + val;
  link.download = 'image.jpg'; // 下载后的文件名
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
}

getRange();
</script>
<style lang='scss' scoped>
.photoContainer {
  flex: 1;
  white-space: nowrap;
  color: #666666;
  padding-top: 16px;
  overflow: overlay;

  .photoRow {
    display: flex;
    align-items: center;
    margin-bottom: 16px;

    .photoItem {
      width: 200px;
      margin-right: 16px;
      padding: 8px;
      display: inline-block;
      font-weight: 500;
      font-size: 14px;
      background-color: #fff;
      // filter: drop-shadow(0px 3px 10px rgba(5, 21, 78, 0.10));
      box-shadow: 1px 4px 10px rgba(0, 0, 0, 0.1);
      /* 水平偏移量 垂直偏移量 模糊半径 阴影颜色 */
      cursor: pointer;

      &:last-of-type {
        margin-right: 0;
      }

      .item-channel {
        background: var(--el-color-primary);
        height: 100%;
        width: 25%;
        color: #fff;
        z-index: 1;
        bottom: 0;
        left: 0;
        display: flex;
        align-items: center;
        justify-content: center;
      }

      .time-text {
        background-color: #000;
        opacity: 0.65;
        height: 100%;
        width: 75%;
        color: #fff;
        z-index: 1;
        display: flex;
        align-items: center;
        justify-content: center;
      }

      .item-info {
        text-align: left;
        color: #6B7A99;
        margin-top: 8px;

        .item-title {
          color: #223355;
          font-size: 16px;
          font-weight: 600;
          line-height: 24px;
        }

        .item-text {
          line-height: 20px;
          font-size: 12px;

          .el-icon {
            margin-right: 4px;
            position: relative;
            top: 2px;
          }
        }
      }
    }
  }
}

.body-top {
  display: flex;
  justify-content: space-between;
  height: 410px;

  .img-dom {
    width: 570px;
    border-radius: 2px;
    position: relative;

    .img-top {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      height: 32px;
      display: flex;

      .chanel-text {
        width: 70px;
        height: 32px;
        line-height: 32px;
        text-align: center;
        background: var(--def, #38F);
        color: var(--unnamed, #FFF);
        font-size: 14px;
        font-weight: 500;
      }

      .other-text {
        width: calc(100% - 70px);
        height: 100%;
        display: flex;
        justify-content: space-between;
        align-items: center;
        color: var(--unnamed, #FFF);
        font-size: 16px;
        font-weight: 600;
        background: rgba(0, 0, 0, 0.56);
        padding: 0 10px;

        .company-name {
          font-size: 12px;
          font-weight: 400;
        }
      }
    }

    .img-left,
    .img-right {
      position: absolute;
      top: 45%;
      right: 12px;
      width: 64px;
      height: 64px;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      background: rgba(0, 0, 0, 0.5);
      cursor: pointer;
      visibility: hidden;
    }

    .img-left {
      left: 12px;

      img {
        transform: rotate(180deg);
      }
    }

    .img-bottom {
      position: absolute;
      bottom: 0;
      height: 44px;
      width: 100%;
      background: rgba(0, 0, 0, 0.3);
      display: flex;
      align-items: center;
      justify-content: flex-end;
      visibility: hidden;

      .downAndFull {
        display: flex;
        margin-right: 20px;
        align-items: center;
        color: #FFF;
        text-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
        font-size: 14px;
        cursor: pointer;

        img {
          width: 16px;
          height: 16px;
          margin-right: 3px;
        }
      }
    }

    &:hover {

      .img-left,
      .img-right,
      .img-bottom {
        visibility: visible;
      }
    }
  }

  .map-dom {
    width: calc(100% - 582px);

    #trajectory_container {
      height: 284px;
      width: 100%;
    }

    .info-dom {
      height: 125px;
      box-shadow: 0px 3px 10px 0px rgba(17, 23, 36, 0.06);
    }

    .info-top {
      height: 64px;
      background: #F4F6FE;
      display: flex;
      align-items: center;
      justify-content: space-between;
      margin-bottom: 10px;

      .driver-dom {
        margin-left: 15px;

        .carNum {
          color: #235;
          font-size: 16px;
          font-weight: 600;
        }

        .name {
          display: flex;
          align-items: center;
          margin-top: 3px;
        }
      }

      .speed-dom {
        width: 65px;
      }

      .s-top {
        color: #878787;
        font-size: 14px;
        font-weight: 400;
      }

      .s-bottom {
        color: var(--9, #1F1F1F);
        font-size: 14px;
        font-weight: 500;
        margin-top: 4px;
      }
    }

    .bottom-dom {
      color: var(--6, #878787);
      font-size: 14px;
      font-weight: 400;
      margin-left: 16px;
      margin-top: 5px;

      .content {
        color: var(--9, #1F1F1F);
        font-size: 14px;
        font-weight: 400;
        margin-left: 11px;
      }
    }
  }
}

.body-bottom {
  height: 120px;
  margin-top: 24px;
  display: flex;
  justify-content: space-between;
  cursor: pointer;

  .arrow-left {
    width: 30px;
    background: #DFE2E7;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-right: 15px;

    img {
      transform: rotate(180deg);
    }

    &:hover {
      background: var(--el-color-primary);
    }
  }

  .arrow-right {
    width: 30px;
    background: #DFE2E7;
    display: flex;
    align-items: center;
    justify-content: center;

    &:hover {
      background: var(--el-color-primary);
    }
  }

  .img-list {
    display: flex;
    justify-content: flex-start;

    .img-item {
      width: 180px;
      height: 120px;
      border-radius: 2px;
      position: relative;
      margin-right: 15px;

      img {
        width: 100%;
        height: 100%;
      }

      .item-mask {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: rgba(0, 0, 0, 0.45);
      }

      .item-active {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        border: 1px solid var(--def, #38F);
        background: rgba(255, 255, 255, 0.00);
        box-shadow: 0px 0px 20px 0px rgba(51, 136, 255, 0.50) inset;
      }
    }
  }
}
</style>